Skip to content

nvx-rs: make the rustdoc and module diagrams describe the final public API (SL6.10g) - #1562

Merged
Pedro Henrique Penna (ppenna) merged 8 commits into
feature/nvx-refactorfrom
agents/slim-sl6-10g-rustdoc
Nov 13, 2026
Merged

Pedro Henrique Penna (ppenna) merged 8 commits into
feature/nvx-refactorfrom
agents/slim-sl6-10g-rustdoc

Conversation

@ppenna

@ppenna Pedro Henrique Penna (ppenna) commented Nov 13, 2026 •

Copy link
Copy Markdown
Contributor

Part of #1131 (SL6.10g, "The rustdoc agrees with the final public API"). Parent #1090, umbrella #1076.

What and why

After every code slice of #1076 merged, the rustdoc of nvx and the module diagrams still described the crate before the slimming: the crate root introduced "NVX mechanics" for the "launch, policy lowering, and supervision" of NVX's sandboxes run by a managed agent; host's and guest's overviews listed NVX's private program code (the CLI's artifacts, policy files, export planner, NVXC session, restore driver and sandbox profile; nvx-init's space, the guest programs and their conventions) beside the library; several item docs named removed mechanisms as current; and doc/modules/ still drew host::{instance, launch, store, supervisor, template}, guest::{exec, spawn, process, cgroup, entry}, the guest's space, NVXC and the CLI. The generator could no longer even draw the crate: SL6.5a2 put host::platform::linux::identity under cfg(any(test, feature = "cli")), which restore() refused.

This PR makes the public rustdoc and the diagrams describe the final public API, as the Scope of SL6.10g says, with doc comments only on the Rust side (no code changes, and the public-API snapshots don't change):

  • Crate and module overviews (lib.rs, host, guest, protocol): the final public modules, Error and ErrorKind included; what the library does not do (it keeps no state, starts OpenVMM and no other process on the host, supervises no VM, takes no lock that its caller sees); what the caller owns, linking the library guide's What the caller owns from doc: describe only the final nvx library in a guide and the READMEs (SL6.10a) #1555 and the guest-agent guidelines; and one paragraph saying that NVX's own programs live in the crate, private, behind hidden entry points. The overviews no longer list private program code. The guest programs' compatibility rules and the guest module's coding conventions move, verbatim, to the private guest::status module that the programs share.
  • NVX's programs out of the public narrative: guest::activation no longer describes nvx-init's application of a record (the text moves, verbatim, to the private guest::activation::state::apply that implements it, whose docs pointed back to the public ones) and points to the guidelines' Build the space; guest::mappings, MappingTable and protocol::maps say that the caller mounts with a mapper of its own, and name the public MappingTable rather than the managed agent as what refuses an empty source; protocol::cmdline names VmConfig::check rather than the CLI's sandbox check; host::network and ExportPlan::check no longer refer to the CLI's private policy files, planner and plan function.
  • No removed module as current API: contract no longer says that "the store" records a VM's versions (the caller saves its RuntimeIdentity), nor that the control contract carries the agent's "features" (NVXC v1's FEATURES); ArtifactIdentity is compared by the library, not "the store"; ErrorKind::NotFound's example is a missing capture manifest, not a sandbox store; SnapshotKey speaks of the runtime, not a "bundle", and no longer "recertifies" templates; CaptureStage::Fence says that no capture has that stage any more (the variant stays, for the API's sake); guest::time names TIME_ABI_VERSION instead of "time ABI v2", which OpenVMM's v4 microVM restarted at 1; Hypervisor and BlockGeometry describe any VM's, not a sandbox's.
  • Intra-doc links: VmmCommand's spawn link names the function (it was ambiguous with the private host::spawn module once private items are documented), the Windows log claim's docs link spawn_with_stdio instead of the deleted spawn_detached, and two redundant explicit links of guest::root go, so that cargo doc --document-private-items passes with warnings denied on both platforms.
  • launch::direct_request said that the workload's standard input is the null device. The request that it builds does read the null device, which its unit test checks, but its only caller replaces it with a pipe for every workload since SL4.4c, so the docs described what no workload gets. They now say both.
  • Module diagrams: scripts/module_diagrams.py draws the crate's public API: public() keeps, in each platform's export before the platforms merge, each module that is public, as are the modules that contain it, but the modules of NVX's programs, which a fixed list, PROGRAMS, names (the CLI, the fake OpenVMM and the eight guest programs: the modules that the public-API snapshots mark (hidden)), and the uses that involve a module that it leaves out; a module that is public on one platform alone is drawn as that platform's. DESCRIPTIONS, the fixed inventory of top-level modules, describes the eight public ones; the test doubles' color goes. restore() accepts any(test, feature = "F") for a feature that the export enables. The page says what the diagrams cover, and that CI draws them every night (the workflow moved to a nightly run in 77bb5e7, but the page still said "after every merge"). doc/ci.md's Module diagrams section follows, and doc/project-structure.md's two mentions of the workflow, which said that it draws the diagrams "after merges", say "every night" (SL6.10e, doc: describe the nvx package's build, release packages and setup (SL6.10e) #1546, which owns that file, merged first). The export, features and targets, the merge, the layout and .github/workflows/module-diagrams.yml don't change, so the nightly run keeps publishing the set.
  • doc/modules/, regenerated by the script (not by hand) with the workflow's tools: overview, dependencies, and the hierarchies of guest, host, net and protocol; activation, gpt and testing contain no public module, so their diagrams go.
  • Case matrix: the doc tests whose lines moved keep their rows under their new names: lib.rs - (line 67) (coverage named by two rows), guest::activation (line 127), MappingTable (line 46), guest::time (line 10). Counts unchanged.

Decisions

  1. The diagrams' scope is the public API, crisp rather than judged: a module is drawn when it and every module that contains it are pub, and it is no program's. The alternative, drawing private library modules dashed but leaving out "program code", needs a judgment for each private module (the OS layers, NVXC, the CLI's sandbox profile, nvx-init's space…) and would still draw the guest's space that SL6.13b made private. PROGRAMS is a fixed list, as the Approach asks ("adjust the generator's fixed public-module inventory … do not introduce discovery"); a program module that a later PR adds shows as public until someone lists it, and its (hidden) line in the public-API snapshot diff is the cue.
  2. The export keeps the cli, testing and guest features, as docs.rs and the public-API snapshots document the crate, so the drawn modules are exactly the snapshots' non-hidden ones (37 on Linux); doc/ci.md's description of the export stays true.
  3. The diagrams were drawn with CI's tools on a Linux host, not on Windows: cargo-modules 0.27.0 built with Rust 1.95.0 on nvx-kvm-test, and Graphviz from Ubuntu 24.04 (graphviz 2.42.2-9ubuntu0.1, dot 2.43.0) with fonts-liberation 1:2.1.5-3 in an ubuntu:24.04 container, so that dev's nightly run, on ubuntu-24.04, finds the same files once this branch reaches dev.
  4. Private docs move rather than go: the guest programs' compatibility rules and conventions, and nvx-init's application, leave the public docs but stay with the private code that they describe.
  5. The scope applies to each platform before the merge, as Copilot's review asked: merge() writes the visibility of a module that differs between platforms as pub on Linux, pub(crate) on Windows, so a filter of the merged crate would lose a module that is public on one platform alone, with its public descendants. No module of the crate has such a visibility today, so the drawn diagrams are the same either way.
  6. "Clone" and "template" stay where they name a VM that a restore starts and the VM whose capture makes a snapshot: the final design docs, the README and the library's own error messages use them. Only the sentences that tied them to the removed template store change.

Tests

python3 scripts/check_test_changes.py --base origin/feature/nvx-refactor lists 4 changed tests, all in scripts/test_module_diagrams.py, and 4 additions:

  • DrawTests.test_draw_exports_each_platform_and_writes_the_page_and_diagrams expects the diagrams of the merge of each platform's public() export, which draw() now draws; the equality of what it drew with them is what checks that draw() applies the scope.
  • DrawTests.test_draw_restores_the_modules_that_cargo_modules_drops_as_tests makes its restored nvx::host::imp public on both platforms, so that the hierarchy that it inspects still draws it; it still checks that the module returns and the test module does not.
  • GraphTests.test_the_overview_shows_every_top_level_module_in_the_crate expects no description of the private error, which DESCRIPTIONS no longer holds.
  • PageTests.test_the_page_leads_to_how_ci_draws_the_diagrams expects "CI draws them again every night".
  • Added: the class PublicTests, with test_the_public_api_leaves_out_private_modules_and_programs (a program, a public module inside it or inside a private module, and the uses that involve them go; public modules and their uses stay) and test_a_module_public_on_one_platform_alone_is_that_platform_s (a module that is pub on Linux and pub(crate) on Windows is drawn, marked Linux's, with its public descendant), and RestoreTests.test_a_test_or_a_feature_that_the_export_enables_builds_outside_tests (any(test, feature = "cli") restores; any(test, feature = "other") still fails). All three fail without the change.

No test is removed. The doc tests are unchanged apart from the lines of the four that move (see the case matrix above).

Size

  • Core lines: 57, in 1 counted file, scripts/module_diagrams.py: public() and its call (20), PROGRAMS (14), the restore() exception (4), DESCRIPTIONS (4), and the page's and the dependency diagram's text (15). This passes SL6.10g's estimate of 0 core lines and no counted files, whose stop is therefore 0: the Scope's "update scripts/module_diagrams.py … for the final diagram scope" needs code, and the generator failed on the final package. The size is accepted, and the script stays in this pull request: see the decision on #1131.
  • The Rust changes are doc comments only (24 files, 0 core lines). The test file, the docs, the case matrix and the generated diagrams don't count.

Commits

  1. nvx-rs: describe the final library and what its caller owns
  2. nvx-rs: leave NVX's programs out of the public rustdoc
  3. nvx-rs: name no removed store, bundle or fence in the rustdoc
  4. nvx-rs: fix the intra-doc links that private items break
  5. guest: say that the managed agent's workloads read a pipe
  6. scripts: restore the modules under a test or an enabled feature
  7. scripts: draw the public modules of nvx in the module diagrams
  8. doc: draw the module diagrams of the final public API

Not in this PR

New public APIs, module moves or compatibility aliases (guest::clone and host::nvxs stay); a new generator, renderer or site; hand edits of doc/modules; the prose guides of SL6.10a–SL6.10f, but for the two mentions of the diagrams' workflow in doc/project-structure.md; renaming "clone" or "template" in the rustdoc; the crate root's links to host, which break in --no-default-features doc builds as before this PR (CI documents with every feature).

Validation

Final rebase. The head, 25cd1567, is 76c51d83 rebased onto 7e5440a1, after SL6.10c, SL6.10b, SL6.10a and SL6.10d, which changed docs only; git range-diff shows every commit unchanged, and rebase_check.py verify passed. The rustdoc's links into the guides, doc/library.md#what-the-caller-owns and doc/guest-agent-guidelines.md#build-the-space, name headings that the final guides hold. At 25cd1567:

  • RUSTDOCFLAGS="-D warnings" cargo doc --locked --no-deps --all-features passed on Windows, for x86_64-unknown-linux-musl, and on Linux, where --features guest passed too.
  • cargo test --locked --all-features --doc passed: 6 on Windows, 15 on Linux.
  • python scripts/public_api.py passed, and the snapshots are unchanged.
  • check_markdown_links.py, check_test_layout.py and SL5.2's check_matrix.py passed; check_test_changes.py lists the same 4 changed and 4 added tests.
  • validate-nvx's Windows step passed: 1806 tests OK, 73 skipped; test_adversarial.py 84 OK, 11 skipped; test_hosts.py 4 OK; the six nvx.py … --help exit 0.
  • Two draws of module_diagrams.py on nvx-kvm-test equal each other and the committed doc/modules, so no diagram changed.
  • CI run 43354639966 passed: 33 jobs succeeded, among them nvx-rs on both platforms, the NVX CLI on both, and the microVM tests on KVM, MSHV and WHP; 9 skipped, the publishing and recording jobs among them.

The rest of this section is the validation of 76c51d83, which was rebased onto e6c65b95, after SL6.10f (#1540) and SL6.10e (#1546), whose docs, instructions and setup READMEs it brought. Its nvx-rs/ is the one that the Rust checks below ran on (git diff 794f9343344 HEAD -- nvx-rs is empty: after them, only the scripts' per-platform filter, its tests and the docs changed); the rows marked "(head)" ran at 76c51d83. The gates are those that dev's local_gates.py (from the orchestration checkout) selects from this branch's own action definitions, once the four check-nvx-rs steps that the feature branch no longer has leave its table: on Windows, test-changes, markdown-links, test-layout, quality-code, nvx-rs-format, nvx-rs-lint, nvx-rs-test, nvx-rs-doc, nvx-rs-msrv and nvx-cli; on Linux, also nvx-rs-public-api, nvx-rs-macos, and the guest binaries' lint and build.

Windows (x86_64-pc-windows-msvc), Rust 1.95.0:

Command Result
cargo fmt --all --check passed
cargo clippy --locked -- -D warnings with --all-targets --all-features, --lib, --lib --no-default-features, --lib --no-default-features --features serde, --lib --bins --features cli, --lib --bins --no-default-features --features testing passed
cargo clippy --locked --target x86_64-unknown-linux-musl -- -D warnings with --lib --all-features and --lib --bins --no-default-features --features guest passed
RUSTDOCFLAGS="-D warnings" cargo doc --locked --no-deps --all-features (Windows, and --target x86_64-unknown-linux-musl) passed
the same with --document-private-items, both targets passed (failed before this PR on four links)
cargo doc with --no-default-features, serde, testing, guest alone only the crate root's three links to host fail, as before this PR
cargo test --locked --all-features, cargo test --locked, cargo build --locked --lib --no-default-features, cargo test --locked --lib --no-default-features passed: 1065 library tests and every integration test with all features; 191 without features
cargo test --locked --all-features --doc 6 passed
cargo +1.89 check --locked --all-targets --all-features passed
python scripts/public_api.py passed: the public API matches the snapshots
python scripts/check_markdown_links.py (head) passed
python scripts/check_test_layout.py (head) passed
python scripts/check_test_changes.py --base origin/feature/nvx-refactor (head) 4 changed, 4 added, as above
ruff check / ruff format --check scripts .github/specula, pyright --pythonplatform Linux / Windows (head) passed: ruff clean, 96 files formatted, pyright 0 errors on both platforms
validate-nvx's Windows step (head): python -m compileall -q scripts, python -m unittest scripts/test_performance.py … scripts/test_public_api.py (22 files, test_nvx_tools.py's doc and README tests among them), scripts\test_adversarial.py, the host-connect skill's test_hosts.py, and the six nvx.py … --help passed: 1806 tests OK, 73 skipped; 84 OK, 11 skipped; 4 OK; all six exit 0
SL5.2's check_matrix.py <worktree> 99d2022085f (head) passed

Linux, nvx-kvm-test (Azure Linux 3, kernel 6.6.159.1-1.azl3), Rust 1.95.0, at b79fce15 (the same nvx-rs/) unless noted:

Command Result
RUSTDOCFLAGS="-D warnings" cargo doc --locked --no-deps with --all-features, --features guest, and --all-features --document-private-items passed
cargo test --locked --all-features --doc 15 passed: 14 and a compile_fail, with the guest's doc tests under the line numbers that the case matrix now names
python3 scripts/nvx.py check-guest-binaries --toolchain 1.95.0 clippy passed; tests 851 passed, 4 failed: guest::init::tests::exec::{a_stolen_or_auto_reaped_status_is_reported_once_and_never_reclassified_by_an_ending, host_launch_tests_use_the_syscall_seam_without_mocking_the_execution_core, native_workload_cwd_accepts_procfs_links_but_closes_inherited_descriptors, only_the_collectors_terminal_status_settles_the_owned_leader_and_output}, which fail the same way at the base f5cc2aac on the same host (the playbook's known kernel 6.6 failures); this PR changes no code
python3 scripts/module_diagrams.py --output doc/modules with cargo-modules 0.27.0 and Graphviz 2.43.0 in ubuntu:24.04, twice, at the head 76c51d83 the second run's files equal the first's (diff -r), and both equal the committed doc/modules (git status --porcelain doc/modules is empty)

Code review: a code-review subagent reviewed the whole diff; its one finding, doc/project-structure.md's "drawn after merges", is fixed now that SL6.10e (#1546), which owns that file, has merged. Copilot's review left one thread, on the merged visibility that public() filtered; public() now filters each platform's export (Decision 5), and the thread is answered and resolved.

Left to CI: on Linux, check-nvx-rs's cargo test (its doc tests ran above; the Rust changes are doc comments), the macOS check, and the guest binaries' build and test; the microVM suites (nothing at run time changes); and module-diagrams.yml, which runs only for pull requests into dev and for dev itself.

@ppenna Pedro Henrique Penna (ppenna) added tests-modified Changes existing tests, test data, or test wiring feat-nvx-refactor labels Nov 13, 2026
@github-actions

github-actions Bot commented Nov 13, 2026 •

Copy link
Copy Markdown
Contributor

This pull request changes existing tests

It modifies or removes 4 existing test asset(s), listed below. Review each with care: a change to a test can hide a regression that the test caught. See doc/contribute.md#changes-to-existing-tests.

Test code

Change What Before After
modified test def GraphTests.test_the_overview_shows_every_top_level_module_in_the_crate in scripts/test_module_diagrams.py scripts/test_module_diagrams.py:558 scripts/test_module_diagrams.py:625
modified test def PageTests.test_the_page_leads_to_how_ci_draws_the_diagrams in scripts/test_module_diagrams.py scripts/test_module_diagrams.py:673 scripts/test_module_diagrams.py:740
modified test def DrawTests.test_draw_exports_each_platform_and_writes_the_page_and_diagrams in scripts/test_module_diagrams.py scripts/test_module_diagrams.py:760 scripts/test_module_diagrams.py:827
modified test def DrawTests.test_draw_restores_the_modules_that_cargo_modules_drops_as_tests in scripts/test_module_diagrams.py scripts/test_module_diagrams.py:791 scripts/test_module_diagrams.py:867

Relocated unchanged: 0; added: 4. Compared the merge base 7e5440a13055 with 25cd1567fc10.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Mixed platform visibility causes Linux-public modules, their public descendants, and uses to disappear from both platforms’ diagrams, requiring per-platform reachability filtering before merging and regression coverage.

1 open issue
What changed in this PR

Aligns nvx rustdoc and module diagrams with the final public API after the library-slimming workstream. Rust changes are documentation-only; generator changes separate the public library from NVX’s private programs.

Changes:

  • Clarifies library mechanisms, caller responsibilities, and private program boundaries.
  • Updates diagram filtering and enabled-feature handling, with corresponding tests and regenerated diagrams.
  • Corrects documentation links, terminology, nightly-generation descriptions, and doctest locations.
File Description
scripts/​test_module_diagrams.py Tests public-module filtering and enabled-feature restoration.
scripts/​module_diagrams.py Filters diagrams to public modules and handles enabled-feature conditions.
nvx-rs/​src/​protocol/​mod.rs Separates public transport from private application protocols.
nvx-rs/​src/​protocol/​maps.rs Clarifies mapping payloads and empty-source restrictions.
nvx-rs/​src/​protocol/​cmdline.rs Names the public configuration validator in documentation.
nvx-rs/​src/​lib.rs Describes the final library and caller responsibilities.
nvx-rs/​src/​hypervisor.rs Generalizes documentation from sandboxes to VMs.
nvx-rs/​src/​host/​vm.rs Disambiguates the spawn rustdoc link.
nvx-rs/​src/​host/​snapshot/​key.rs Updates runtime and snapshot compatibility terminology.
nvx-rs/​src/​host/​runtime/​mod.rs Removes obsolete store references from identity docs.
nvx-rs/​src/​host/​platform/​windows/​log_claim.rs Corrects spawn-function links in private documentation.
nvx-rs/​src/​host/​network/​mod.rs Focuses the overview on public network-policy lowering.
nvx-rs/​src/​host/​mod.rs Documents public host mechanisms and caller ownership.
nvx-rs/​src/​host/​filesystem/​verify.rs Describes export-plan requirements without private planner references.
nvx-rs/​src/​host/​config/​mod.rs Generalizes block-geometry documentation to VMs.
nvx-rs/​src/​guest/​time/​mod.rs Links the time ABI version constant.
nvx-rs/​src/​guest/​status.rs Houses private guest-program compatibility rules and conventions.
nvx-rs/​src/​guest/​root.rs Removes redundant explicit rustdoc link targets.
nvx-rs/​src/​guest/​mod.rs Presents public guest mechanisms separately from private programs.
nvx-rs/​src/​guest/​mappings/​table.rs Describes caller-owned mapper initialization.
nvx-rs/​src/​guest/​mappings.rs Clarifies mapping ownership and aggregate-export restrictions.
nvx-rs/​src/​guest/​managed_agent/​launch.rs Documents replacement of default stdin with a streaming pipe.
nvx-rs/​src/​guest/​activation/​state/​apply.rs Receives private activation-application documentation.
nvx-rs/​src/​guest/​activation.rs Separates public activation from private space assembly.
nvx-rs/​src/​error.rs Replaces the obsolete store example for NotFound.
nvx-rs/​src/​contract.rs Updates identity, protocol, and snapshot terminology.
doc/​modules/​README.md Explains public diagram scope and nightly generation.
doc/​modules/​overview.svg Regenerates the public-module overview.
doc/​modules/​nvx-testing.svg Removes the private testing-program hierarchy.
doc/​modules/​nvx-protocol.svg Regenerates the public protocol hierarchy.
doc/​modules/​nvx-gpt.svg Removes the hierarchy of private GPT submodules.
doc/​modules/​nvx-activation.svg Removes the hierarchy of private activation submodules.
doc/​modules/​dependencies.svg Regenerates dependencies between retained public modules.
doc/​ci.md Documents diagram filtering and restoration behavior.
doc/​acceptance-case-matrix.md Updates relocated doctest line references.

Review effort: Balanced

Comment thread scripts/module_diagrams.py Resolved

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Approval recommended

No active review issues block the documentation and public-module diagram updates.

No open issues 🎉

1 resolved since last review

Review effort: Balanced

The crate's rustdoc still introduced nvx as "NVX mechanics" for the
launch, policy lowering and supervision of NVX's sandboxes, whose guest
init starts a managed agent, and listed NVX's own programs and their
private code among the modules of the library: the CLI's artifacts,
policy files, export planner, control session, restore driver and
sandbox profile in host's overview, and nvx-init's space, the guest
programs and their conventions in guest's. After the slimming, the
library supervises nothing, keeps no state, and its programs are private
to the crate.

The crate root now describes the library as the final README and the
library guide do: a VM's configuration and launch in a directory that
the caller owns, one snapshot type, caller-driven restores, verified
connections and reattachment, the contracts of a guest's space, and the
guest's side of a capture and of a restore's activation. It says that
the library starts OpenVMM and no other process, supervises no VM, and
leaves its state, paths, locks, protocol, deadlines and recovery to its
caller, and links the library guide's "What the caller owns", beside
the guest-agent guidelines. Its module list covers the final public
modules, Error and ErrorKind included, and one paragraph says that
NVX's own programs live in the crate, private, behind hidden entry
points.

host's overview lists its public modules alone, with vm's spawn, stop,
verify and reattach, and snapshot's directory and finish_capture, and
says what the library does not do: it keeps no record, takes no lock
that its caller sees, and supervises no VM. Its notes on the modules'
order and on unsafe code stay, naming spawn and platform as private.

guest's overview lists the calls on which any init or agent builds, and
says that the library builds no space and runs no execution, as the
guidelines' worked example, nvx-init, shows; its excerpt stays as the
guidelines quote it. The programs' compatibility with the C programs
that they replace, and the conventions of the module's code, which
concern the private programs, move to the private status module, whose
programs share them. protocol's overview no longer lists the programs
that speak NVX's own protocol, which is private.

Part of #1131 (SL6.10g).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The public docs of several modules described the code of NVX's own
programs, which is private to the crate, as part of what a caller reads
and uses:

- guest::activation described nvx-init's application of a restore's
  record, its assembly inputs, GPT reread, fresh upper, export mount,
  view, and teardown, and the privileges that the application needs.
  The public docs now say that each adapter applies the record in its
  own space, which the library leaves alone, and point to the
  guidelines' "Build the space"; the description moves, unchanged, to
  the private module that implements it, guest::activation::state::
  apply, whose docs pointed back to the public ones.
- guest::mappings and MappingTable described how NVX mounts mappings
  and how its managed agent applies its table. They now say that the
  caller mounts the mappings through a mapper of its own, that NVX's
  is private, and that a table refuses an empty source, since its
  entries come from an aggregate export.
- protocol::maps described the MAPS payloads as what NVX's control
  protocol, NVXC, hands its agent. They now describe the table on the
  wire, which a host sends in its own protocol, as NVX's APP_MAPS
  requests do, and name the public MappingTable as what refuses an
  empty source, rather than NVX's managed agent.
- protocol::cmdline named the CLI's check of a sandbox's kernel
  parameters among the readers of the init's tokens. The public reader
  is VmConfig::check of a boot's own tokens, which it now names.
- host::network's summary named the CLI's private policy files, and
  ExportPlan::check described a valid plan as one that the CLI's
  private planner could make, with its paths in the form in which its
  private plan function resolves them. Both now describe the public
  behavior alone, the form of the paths spelled out.

The example of NVX's programs as callers, such as the CLI's rechecks of
an export plan, stays where it illustrates what a caller owns.

Part of #1131 (SL6.10g).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The public rustdoc still named mechanisms that the slimming removed as
if they were current:

- contract said that "the store" records a VM's contract versions in
  its runtime identity. The library keeps no store: its caller saves
  the runtime identity with each VM, in its SavedVm, and the docs now
  say so. CONTROL_CONTRACT_REVISION's versioned contract named "the
  features of the guest agent", which went with NVXC v1's FEATURES; it
  now names the requests and responses of NVX's own protocol. The
  compatibility key is a snapshot's, and an earlier OpenVMM's snapshot,
  rather than its template, is what the format refuses.
- ArtifactIdentity, and the private token that it holds, were opaque
  tokens that "the store only compares": the library compares them.
- ErrorKind::NotFound took the store of a sandbox as its example; it
  now takes the manifest of a capture that OpenVMM never wrote, which
  SnapshotManifest::read reports with that kind.
- SnapshotKey's docs called the runtime's artifacts a bundle, the name
  of the feature that went, and said that the templates of an old key
  are "not recertified", which the template store did. A runtime that
  changes an artifact now makes snapshots of a new key, restores none
  of the old key's, and they are captured again.
- CaptureStage::Fence documented the closing of an admission fence,
  which the capture no longer holds: no capture has the stage, which
  stays for the API's sake, and its docs now say so.
- guest::time called its ABI "NVX time ABI v2", which OpenVMM's v4
  microVM restarted at version 1; it now names TIME_ABI_VERSION.
- Hypervisor and BlockGeometry described a sandbox's VMs and devices;
  they describe any VM's.

The public API does not change.

Part of #1131 (SL6.10g).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
CI documents the public API, whose links resolve, but rustdoc with
--document-private-items, as a contributor runs it, failed on four
links with warnings denied:

- VmmCommand's docs, public, linked `spawn`, which resolves to the
  public vm::spawn alone, but to both it and the private host::spawn
  module once private items are documented. The link now names the
  function.
- Three docs of the Windows platform's log claim linked
  spawn_detached, which a cold blockless launch's switch to the
  verified lifecycle replaced with spawn_with_stdio, detached; they
  link spawn_with_stdio.
- Two docs of the guest's root gave an explicit target to a link that
  resolves without one, which rustdoc refuses as redundant.

With these, rustdoc documents the private items of both platforms with
warnings denied.

Part of #1131 (SL6.10g).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
direct_request's docs said that the workload's standard input is the
null device. The request that it builds reads the null device, which
its unit test checks, but its one caller, the managed agent's launch,
replaces it with a pipe for every workload, since SL4.4c streams each
execution's input over NVXC v2 and SL4.4d deleted v1's null standard
input. Read alone, the docs described what no workload gets.

They now say that the request reads the null device, which the agent's
launch replaces with a pipe, since every execution streams its input.
The code does not change.

Part of #1131 (SL6.10g).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
module_diagrams.py could no longer draw the diagrams of the crate:

    error: cannot restore the modules of x86_64-unknown-linux-musl:
    nvx::host::platform::linux::identity builds under
    cfg(any(test, feature = "cli"))

SL6.5a2 (#1125) gated the Linux platform's identity module, which only
the CLI and the tests read, with cfg(any(test, feature = "cli")).
cargo-modules drops it from its plain analysis as a test module, since
it folds a condition with test true and every other condition false,
and the script refuses to restore a module under any condition that
depends on test but test itself, since it cannot tell whether the
module builds outside tests.

It can for this one: the export enables the cli feature, so the
condition holds outside tests too. The script now restores a module
under any(test, feature = "F") of a feature F that the export enables,
as it restores one under cfg(not(windows)), and refuses the condition
of any other feature, which may hold for tests alone, as before.

A test of the restoration checks both: a module under
any(test, feature = "cli") returns, and one under
any(test, feature = "other") fails, as conditions that depend on test
otherwise do.

doc/ci.md's Module diagrams section, which says where the script stops,
names the exception.

Part of #1131 (SL6.10g).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The module diagrams drew every module of the crate's library, private
ones dashed, so they showed NVX's own programs, which the slimming made
private or hid, as part of the crate: the CLI and the fake OpenVMM with
their dozens of modules, the guest programs, nvx-init's space, NVXC,
the OS layers. Their inventory of top-level modules described modules
that are gone or private, such as exec, error, hypervisor and testing,
and host as "Launch and supervision"; and their page said that CI draws
them after every merge to dev, which it stopped doing when the workflow
moved to a nightly run.

The diagrams now show the crate's public API, as the public-API
snapshots list it: public() keeps each module that is public, as are
the modules that contain it, but the modules of NVX's programs, which
the crate makes public only for the hidden entry points of its
binaries, and the modules that they contain. PROGRAMS names them, a
fixed list, as DESCRIPTIONS is: the CLI, the fake OpenVMM, and the
eight guest programs. The uses that involve a module that it leaves out
go with it. It filters each platform's export before the merge, so that
a module that is public on one platform alone is drawn as that
platform's, rather than lost to a merged visibility that names both.
The export, its features and targets, the restoration of the modules
that cargo-modules takes for tests, the merge, the layout and the
workflow stay as they are.

DESCRIPTIONS describes the eight public top-level modules, and the
amber of the test doubles goes. The page says that the diagrams cover
the public API and leave out the private modules and the programs, that
every box is a public module, that the dependencies leave out the uses
of the modules that the diagrams leave out, and that CI draws them
every night, as the workflow does since it moved to a nightly run.
doc/ci.md's Module diagrams section says that the diagrams show the
public modules, and that the script keeps those of the public API,
without the modules of NVX's programs, and doc/project-structure.md's
two mentions of the workflow say that it draws them every night.

Tests: two new tests check that the public API keeps the public modules
and their uses, and leaves out a program, a public module inside it or
inside a private module, and the uses that involve them; and that a
module that is public on one platform alone is drawn as that platform's.
Three tests change with the scope:

- test_draw_exports_each_platform_and_writes_the_page_and_diagrams
  expects the diagrams of the public API, which draw() now draws.
- test_draw_restores_the_modules_that_cargo_modules_drops_as_tests
  makes its restored module, nvx::host::imp, public on both platforms,
  so that the diagram that it inspects still draws it; it still checks
  that the module returns, and that the test module does not.
- test_the_overview_shows_every_top_level_module_in_the_crate expects
  no description of error, which DESCRIPTIONS no longer holds, since it
  is private.

test_the_page_leads_to_how_ci_draws_the_diagrams expects the nightly
drawing. The tests' docstring follows.

Part of #1131 (SL6.10g).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
feature/nvx-refactor's diagrams were those that dev's nightly run drew
before the slimming, with only the exec engine's section removed by
hand: they still showed host::{instance, launch, store, supervisor,
template}, guest::{exec, spawn, process, cgroup, entry}, the guest's
space, NVXC's protocol::app, the CLI and the fake OpenVMM.

module_diagrams.py drew them again, in their final scope, the crate's
public API: the eight public top-level modules, and the modules of
guest, host, net and protocol. activation, gpt and testing contain no
public module, so their hierarchies go, testing's with the module.

The drawing used the tools of the workflow's draw job: cargo-modules
0.27.0 built with Rust 1.95.0, and Graphviz 2.43.0 (Ubuntu 24.04's
graphviz 2.42.2-9ubuntu0.1) with fonts-liberation 1:2.1.5-3, in an
ubuntu:24.04 container on nvx-kvm-test, so that dev's nightly run,
which draws on ubuntu-24.04 with those tools, finds the same files
once this branch reaches dev. A second run drew the same files, byte
for byte.

Part of #1131 (SL6.10g).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@ppenna
Pedro Henrique Penna (ppenna) marked this pull request as ready for review November 13, 2026 02:47
@ppenna
Pedro Henrique Penna (ppenna) merged commit 21e37b7 into feature/nvx-refactor Nov 13, 2026
85 checks passed
@ppenna
Pedro Henrique Penna (ppenna) deleted the agents/slim-sl6-10g-rustdoc branch November 13, 2026 03:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feat-nvx-refactor tests-modified Changes existing tests, test data, or test wiring

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants